package com.byinsight.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import org.springframework.beans.factory.annotation.Autowired;

import com.byinsight.service.DimensionService;
import com.byinsight.service.dto.Dimension;
import com.byinsight.web.actions.util.DimensionHelper;

import eg.backend.manager.DimensionManager;
import eg.backend.manager.ExpenseManager;
import eg.backend.manager.UserManager;
import eg.backend.util.Constants;

public class DimensionServiceImpl implements DimensionService {
	@Autowired
	private DimensionManager dimensionManager;
	@Autowired
	private ExpenseManager expenseManager;
	@Autowired
	private UserManager userManager;
	private static final Logger logger = Logger.getLogger(DimensionServiceImpl.class.getName());
	
	public eg.backend.domain.Dimension updateDimension(Dimension rootDimension) {
		logger.warning("begin updateDimension");
		eg.backend.domain.Dimension dimension = DimensionHelper.fromDto(rootDimension);
		
		//update expenses
		updateExpensesOnDimDeleted(dimension);
		//save dimension tree
		dimension = dimensionManager.update(dimension);
		return dimension;
	}
	
	public List<Dimension> getDimensions4Input() {
		List<Dimension> dimensions = new ArrayList<Dimension>();
		List<eg.backend.domain.Dimension> systemDims = dimensionManager.getSystemDimensions();
		for(eg.backend.domain.Dimension d : systemDims)
			dimensions.add(DimensionHelper.toDto(d));
		List<eg.backend.domain.Dimension> systemShared = dimensionManager.getSystemSharedDimensions();
		for(eg.backend.domain.Dimension d : systemShared) {
			if(!isInCollection(dimensions, d.getEncodedKey()))
					dimensions.add(DimensionHelper.toDto(d));
		}
		if(!Constants.USER_SYSTEM_NAME.equals(userManager.getCurrentUsername())) {
			logger.warning("user is NOT SYSTEM, go retrieve userDimensions");
			List<eg.backend.domain.Dimension> users = dimensionManager.getUserDimensions();
			for(eg.backend.domain.Dimension d : users) {
				if(!isInCollection(dimensions, d.getEncodedKey()))
						dimensions.add(DimensionHelper.toDto(d));
			}
		} else {
			logger.warning("user is SYSTEM, not retrieve userDimensions");
		}
		logger.warning("finished getDimensions4Input.");
		return dimensions;
	}
	
	private void updateExpensesOnDimDeleted(eg.backend.domain.Dimension dimension) {
		List<eg.backend.domain.Dimension> deleted = dimensionManager.getDeleted(dimension);
		List<String> deletedIds = new ArrayList<String>();
		for(eg.backend.domain.Dimension item : deleted) 
			deletedIds.add(item.getEncodedKey());
		for(eg.backend.domain.Dimension child : deleted) {
			List<String> expenses = expenseManager.findChildrenIdsByDimension(child.getEncodedKey());
			String parent = expenseManager.getEffectiveParent(child, deletedIds);
			for(String expense : expenses) {
				expenseManager.addDimension2Expense(expense, parent);
			}
		}
	}
	
	private boolean isInCollection(List<Dimension> list, String id) {
		for(Dimension dim : list)
			if(dim.getEncodedKey().equals(id))
				return true;
		return false;
	}
}
